package ucl.cs.stockBroker.server;

/**
 * Account Implementation.
 * @author  K. Bryson.
 * @version 1.0
 */
///////////////// WHY DOES THIS NOT WORK CORRECTLY ? //////////////////
//added pin instance var + method (mohamad).

import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import ucl.cs.stockBroker.common.Account;

public class AccountImpl extends java.rmi.server.UnicastRemoteObject implements
		Account {

	// This supports serialization.
	static final long serialVersionUID = 1;

	private String name;
	private int number;
	private String pin;
	private float balance = 0.0f;
	private Map<String, Integer> shares;// Map of shares contains <company
										// Symbol,numberOfShares>.

	public AccountImpl(String name, int account_number, String pin) throws RemoteException {
		super();
		this.name = name;
		this.pin = pin;
		this.number = account_number;
		shares = new HashMap<String, Integer>();
	}

	public AccountImpl(String name, int account_number, String pin,
			float balance, Map<String, Integer> shares) throws RemoteException {
		super();
		this.name = name;
		this.pin = pin;
		this.number = account_number;
		this.balance = balance;
		this.shares = shares;
	}

	public void deposit(float amount) throws RemoteException {
		System.out.println(name + ": Depositing " + amount);
		float tmp = balance + amount;
		threadRest();
		balance = tmp;
	}

	public void withdraw(float amount) throws RemoteException {
		System.out.println(name + ": Withdrawing " + amount);
		float tmp = balance - amount;
		threadRest();
		balance = tmp;
	}

	public String getName() {
		return name;
	}

	public int getNumber() {
		return number;
	}

	public String getPin() {
		return pin;
	}

	public float getBalance() {
		return balance;
	}

	public Map<String, Integer> getShares() {
		return shares;
	}

	public int getShareQuantity(String symbol) {
		int quantity = 0;
		for (Entry<String, Integer> share : shares.entrySet()) {
			if (share.getKey().equalsIgnoreCase(symbol)) {
				quantity = share.getValue();
				break;
			}
		}
		return quantity;
	}

	public String getDescription() throws RemoteException {
		String accDescription = "Account number: " + number
				+ "\n   Account name: " + name + "\n   Balance: " + balance;
		if (shares.isEmpty()) {
			accDescription = accDescription
					+ ("\n   This account has no shares.");
		}

		for (Map.Entry<String, Integer> entry : shares.entrySet()) {
			accDescription = accDescription
					+ ("\n   Company: " + entry.getKey()
							+ ", Number Of Shares: " + entry.getValue());
		}
		return accDescription;
	}

	public void addShare(String symbol, int quantity) {
		// find share is already exists
		int existingQuantity = getShareQuantity(symbol);

		if (existingQuantity == 0) {
			shares.put(symbol, quantity);
		} else {
			for (Entry<String, Integer> share : shares.entrySet()) {
				if (share.getKey().equalsIgnoreCase(symbol)) {
					System.out.println(share.getKey() + " " + share.getValue()); // test
					int units = quantity + share.getValue();
					shares.put(symbol, units);
					break;
				}
			}
		}
	}

	public void removeShare(String symbol, int quantity) throws RemoteException {
		if (getShareQuantity(symbol) > quantity) {
			shares.put(symbol, shares.get(symbol) - quantity);
		} else if (getShareQuantity(symbol) == quantity) {
			shares.remove(symbol);
		}
	}

	private void threadRest() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException except) {
		}
	}

}
